﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Platformer1
{
    /// <summary>
    /// Facing direction along the X axis.
    /// </summary>


    /// <summary>
    /// A monster who is impeding the progress of our fearless adventurer.
    /// </summary>
    class CustomEnemy : Player
    {
        public int ai_style = 0;
        protected float waitTime;
        protected const float MaxWaitTime = 0.5f;
        protected  float MoveSpeed = 128.0f;
        protected FaceDirection direction = FaceDirection.Left;
        protected bool isPouncing = false;
        protected bool isPounced = false;
        public SpriteFont hudFont;
        private Animation pounchAnimation;
        private Animation idlePounceAnimation;
        protected float deadTime = 1;
        public bool deadDraw = false;
        public float hitByX;
        bool hitonce = false;
        public int hitBackAmt = 0;
        public string eType = "";

        public override void GetInput()
        {
            if (IsAlive)
            {
                if (ai_style == 0)
                {
                    chaseAI();
                }
                else if (ai_style == 1)
                {
                    patrolAI();
                }
                else if (ai_style == 2)
                {
                    StillShotAI();
                }
                else if (ai_style == 3)
                {
                    SmartShotAI();
                }
                else if (ai_style == 4)
                {
                    PounceAI();
                }
                else if (ai_style == 5)
                {

                }
            }
        }

        public CustomEnemy(Level level, Vector2 in_position)
            : base()
        {
            this.Level = level;
            hudFont = level.Content.Load<SpriteFont>("Fonts/Hud");
            //LoadEnemy();

            Position = in_position;
            Reset(Position);
            debug = Level.Content.Load<Texture2D>("debug");
        }
        public CustomEnemy()
        {
            spriteType = SpriteType.ST_Enemy;
        }
        new public void OnKilled(Enemy killedBy)
        {
            if (hitonce)
            {
                base.OnKilled(null);

            }
            else
            {
                hitonce = true;
                if (hitByX > Position.X)
                {
                    hitBackAmt += 2;
                }
                else
                {
                    hitBackAmt -= 2;
                }
            }

        }


        public void LoadEnemy()
        {
            //idleAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Idle"), 0.1f, true);
            //runAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Run"), 0.1f, true);
            //jumpAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Run"), 0.1f, false);
            //celebrateAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Run"), 0.1f, false);
            //dieAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //punchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //jumpPunchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //crouchPunchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //kickAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //jumpKickAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //crouchKickAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);
            //crouchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/MonsterA/Die"), 0.1f, false);

            idleAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/idle"), 0.1f, true);
            runAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Run"), 0.1f, true);
            jumpAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Jump"), 0.1f, false);
            celebrateAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Celebrate"), 0.1f, false);
            dieAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Die"), 0.1f, false);
            punchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Punch"), 0.1f, true);
            jumpPunchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Jump_Punch"), 0.1f, true);
            crouchPunchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Crouch_Punch"), 0.1f, true);
            kickAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Kick"), 0.1f, true);
            jumpKickAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Jump_Kick"), 0.1f, true);
            crouchKickAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Crouch_Kick"), 0.1f, true);
            crouchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Crouch"), 0.1f, true);
            shootAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Shoot"), 0.1f, true);

            pounchAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Jump_Punch"), 0.1f, true);
            idlePounceAnimation = new Animation(Level.Content.Load<Texture2D>("Sprites/OliveMan/Crouch_Punch"), 0.1f, true);

            int width = (int)(idleAnimation.FrameWidth * 0.4);
            int left = (idleAnimation.FrameWidth - width) / 2;
            int height = (int)(idleAnimation.FrameWidth * 0.8);
            int top = idleAnimation.FrameHeight - height;
            localBounds = new Rectangle(left, top, width, height);

            LoadSoundEffects();

 
            MoveAcceleration = 7000.0f;
            MaxMoveSpeed = 1000.0f;
        }
        new public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            // Flip the sprite to face the way we are moving.
            if (Velocity.X < 0)
                flip = SpriteEffects.FlipHorizontally;
            else if (Velocity.X > 0)
                flip = SpriteEffects.None;
            else
            {
                if (direction == FaceDirection.Left)
                {
                    flip = SpriteEffects.None;
                }
                else
                {

                    flip = SpriteEffects.FlipHorizontally;
                }
            }


            // Draw that sprite.

            if (IsAlive)
            {

                sprite.Draw(gameTime, spriteBatch, Position, flip);
            }
            else if (!IsAlive && deadTime > 0)
            {
                deadTime = Math.Max(0.0f, deadTime - (float)gameTime.ElapsedGameTime.TotalSeconds);
                if (deadDraw)
                {
                    sprite.Draw(gameTime, spriteBatch, Position, flip);
                    deadDraw = false;
                }
                else
                {
                    deadDraw = true;
                }
            }
            //Rectangle hitBox = this.getCurrentHitBox();
            //if (hitBox != Rectangle.Empty)
            //{
            //    spriteBatch.Draw(debug, hitBox, Color.Red);
            //}


            //float posX = Position.X + localBounds.Width / 2 * (int)direction;
            //int tileX = (int)Math.Floor(posX / Tile.Width) - (int)direction;
            //int tileY = (int)Math.Floor(Position.Y / Tile.Height);
            //spriteBatch.DrawString(hudFont, tileX.ToString(), new Vector2(200, 100), Color.White);
            //spriteBatch.DrawString(hudFont, tileY.ToString(), new Vector2(200, 150), Color.White);


        }
        public void Suicide()
        {
            //TODO HERE;
            //IsAlive = false;
        }
        new public void Update(GameTime gameTime)
        {
            g_time = gameTime;

            GetInput();
            if (hitBackAmt != 0)
            {
                movement = hitBackAmt;
                hitBackAmt = 0;
            }
            ApplyPhysics(gameTime);

            /*if (IsAlive && IsOnGround && isCrouching)
            {
                if (isPunching)
                {
                    sprite.PlayAnimation(crouchPunchAnimation);
                }
                else if (isKicking)
                {
                    sprite.PlayAnimation(crouchKickAnimation);
                }
                else
                {
                    sprite.PlayAnimation(crouchAnimation);
                }
            }
            else*/
            if (IsAlive && IsOnGround)
            {
                if (isPunching)
                {
                    sprite.PlayAnimation(punchAnimation);
                }
                else if (isKicking)
                {
                    sprite.PlayAnimation(kickAnimation);
                }
                else if (Math.Abs(Velocity.X) - 0.02f > 0)
                {
                    sprite.PlayAnimation(runAnimation);
                }
                else if (isShooting)
                {
                    sprite.PlayAnimation(shootAnimation);
                }
                else
                {
                    if (ai_style != 4)
                    {
                        sprite.PlayAnimation(idleAnimation);
                    }
                    else if (ai_style == 4 && isPounced == true)
                    {
                        sprite.PlayAnimation(idleAnimation);
                    }
                    else if (ai_style == 4 && isPounced == false && isPouncing == false)
                    {
                        sprite.PlayAnimation(idlePounceAnimation);
                    }
                    else if (ai_style == 4 && isPounced == false && isPouncing == true)
                    {
                        sprite.PlayAnimation(pounchAnimation);
                        if (sprite.FrameIndex == sprite.Animation.FrameCount - 1)
                        {
                            isPouncing = false;
                            isPounced = true;
                            ai_style = 0;
                        }

                    }

                }
            }
            else if (IsAlive)
            {
                if (isPunching)
                {
                    sprite.PlayAnimation(jumpPunchAnimation);
                }
                else if (isKicking)
                {
                    sprite.PlayAnimation(jumpKickAnimation);
                }
                else if (isShooting)
                {
                    sprite.PlayAnimation(shootAnimation);
                }
            }

            // Clear input.
            movement = 0.0f;
            isJumping = false;

            
        }
        private void chaseAI()
        {
            Player p = Level.getClosestPlayer(this.Position);
            float posX = Position.X + localBounds.Width / 2 * (int)direction;
            int tileX = (int)Math.Floor(posX / Tile.Width) - (int)direction;
            int tileY = (int)Math.Floor(Position.Y / Tile.Height);



            if (p.Position.X > Position.X)
            {
                direction = FaceDirection.Left;
            }
            else
            {
                direction = FaceDirection.Right;
            }

            //TileCollision t = Level.GetCollision(59, 15);


            //if (Level.GetCollision(tileX + (int)direction, tileY +1 ) == TileCollision.Passable)
            //{
            //    movement = 0;
            //    return;
            //}
            // If we are about to run into a wall or off a cliff, start waiting.
            //if (Level.GetCollision(tileX + (int)direction, tileY - 1) == TileCollision.Impassable ||
            //    Level.GetCollision(tileX + (int)direction, tileY) == TileCollision.Passable)
            //{
            //    int a = 0;
            //}
            GameTime gameTime = g_time;

            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;




            if (Math.Abs(p.Position.X - Position.X) < 50 && Math.Abs(p.Position.Y - Position.Y) < 50)
            {
                movement = 0;
                isPunching = true;
                if (isPunching && sprite.FrameIndex == sprite.Animation.FrameCount - 1)
                {
                    //sprite.FrameIndex = 0;
                    isPunching = false;
                    sprite.PlayAnimation(punchAnimation);
                }
            }
            else if (Math.Abs(p.Position.X - Position.X) > 10 && p.Position.Y - Position.Y >= 0)
            {
                isPunching = false;
                if (p.Position.X > Position.X)
                {
                    movement = 1;
                }
                else
                {
                    movement = -1;
                }
            }
            else if (Math.Abs(p.Position.X - Position.X) > 10 && p.Position.Y - Position.Y < 0)
            {
                isPunching = false;
                isJumping = true;

                if (p.Position.X > Position.X)
                {
                    movement = 1;
                }
                else
                {
                    movement = -1;
                }
            }


            // If we are about to run into a wall or off a cliff, start waiting.
            //if (Level.GetCollision(tileX   + ((int)direction *2), tileY - 1) == TileCollision.Impassable)
            //{                   

            //    movement *= -1;

            //}


        }
        public virtual void patrolAI()
        {
            GameTime gameTime = g_time;
            Player p = Level.getClosestPlayer(this.Position);
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // Calculate tile position based on the side we are walking towards.
            float posX = Position.X + localBounds.Width / 2 * (int)direction;
            int tileX = (int)Math.Floor(posX / Tile.Width) - (int)direction;
            int tileY = (int)Math.Floor(Position.Y / Tile.Height);

            if (Math.Abs(p.Position.X - Position.X) < 50 && Math.Abs(p.Position.Y - Position.Y) < 50)
            {
                movement = 0;
                isPunching = true;
                if (sprite.FrameIndex == sprite.Animation.FrameCount - 1)
                {
                    //sprite.FrameIndex = 0;

                    if (p.Position.X > Position.X)
                    {
                        movement = 1;
                        direction = FaceDirection.Left;
                    }
                    else
                    {
                        movement = -1;
                        direction = FaceDirection.Right;
                    }


                    isPunching = true;
                    sprite.PlayAnimation(punchAnimation);
                    isPunching = false;
                }
                return;
            }
            else
            {
                isPunching = false;
            }

            if (ai_style == 1)
            {
                if (waitTime > 0)
                {
                    // Wait for some amount of time.
                    waitTime = Math.Max(0.0f, waitTime - (float)gameTime.ElapsedGameTime.TotalSeconds);
                    if (waitTime <= 0.0f)
                    {
                        // Then turn around.
                        direction = (FaceDirection)(-(int)direction);
                    }
                }
                else
                {
                    // If we are about to run into a wall or off a cliff, start waiting.
                    if (Level.GetCollision(tileX + (int)direction, tileY - 1) == TileCollision.Impassable ||
                        Level.GetCollision(tileX + (int)direction, tileY) == TileCollision.Passable)
                    {
                        waitTime = MaxWaitTime;
                    }
                    else
                    {
                        // Move in the current direction.
                        velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f);
                        Position = Position + velocity;
                        //movement = (int)direction * MoveSpeed * elapsed;
                    }
                }
            }

        }
        private void StillShotAI()
        {

            isShooting = true;
            if (sprite.FrameIndex == sprite.Animation.FrameCount - 1)
            {
                isShooting = false;
                sprite.PlayAnimation(shootAnimation);
            }


        }
        private void SmartShotAI()
        {
            Player p = Level.getClosestPlayer(this.Position);
            if (p.Position.X > Position.X)
            {
                direction = FaceDirection.Left;
            }
            else
            {
                direction = FaceDirection.Right;
            }
            isShooting = true;
            if (sprite.FrameIndex == sprite.Animation.FrameCount - 1)
            {
                isShooting = false;
                sprite.PlayAnimation(shootAnimation);
            }
        }
        private void PounceAI()
        {
            Player p = Level.getClosestPlayer(this.Position);
            if (Math.Abs(p.Position.X - Position.X) < 50 && Math.Abs(p.Position.Y - Position.Y) < 50)
            {
                movement = 0;
                isPouncing = true;
            }
        }
        private void FallAI()
        {
            if (velocity.Y == 0)
            {
                ai_style = 1;
            }
        }

    }
}
